iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
佛心分享-SideProject30

用 Golang 實作 streamlit 系列 第 16

Day16 Go Embed Build Assets

  • 分享至 

  • xImage
  •  

由於 build 完整個 Frontend Project 會不只 index.html, 和 index.js ,後端的 embed 也要進行修改。

toolgui/toolgui-web/app/build$ tree .
.
├── asset-manifest.json
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── robots.txt
└── static
    ├── css
    │   ├── main.036bff31.css
    │   └── main.036bff31.css.map
    └── js
        ├── 317.406936a5.chunk.js
        ├── 317.406936a5.chunk.js.map
        ├── main.65de86a6.js
        ├── main.65de86a6.js.LICENSE.txt
        └── main.65de86a6.js.map

資料夾底下有三類:

  • Index html
  • Static folder
  • 其他檔案

之所以把 Index html 和其他檔案特別拉出來而不是直接用 embed.FS 吃下整個 build folder,是因為我們之後需要支援 multipage,設計的 mulitpage url 就是 /(page-name) ,這樣就需要保留第一層的檔案。

Static folder 要用 embed.FS 吃下,以方便 http server 去 serve :

// toolgui-web/web.go

//go:embed app/build/static/*
var staticDir embed.FS

func GetStaticDir() fs.FS {
	fsys, err := fs.Sub(staticDir, path.Join("app", "build"))
	if err != nil {
		panic(err)
	}
	return fsys
}

// toolgui/tgexec/web.go
mux.Handle("GET /static/", http.FileServerFS(toolguiweb.GetStaticDir()))

Index 直接用老方法 Serve

// toolgui-web/web.go

//go:embed app/build/index.html
var IndexBody string

// toolgui/tgexec/web.go
func (e *WebExecutor) handleIndex(resp http.ResponseWriter, req *http.Request) {
	resp.Write([]byte(toolguiweb.IndexBody))
}

其他檔案就預先整理成一個 map,然後按名字 serve:

// toolgui-web/web.go

//go:embed app/build/*
var rootAssets embed.FS

func GetRootAssets() map[string][]byte {
	entries, err := rootAssets.ReadDir(path.Join("app", "build"))
	if err != nil {
		panic(err)
	}

	files := map[string][]byte{}

	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}

		bs, err := rootAssets.ReadFile(path.Join("app", "build", entry.Name()))
		if err != nil {
			panic(err)
		}

		files[entry.Name()] = bs
	}
	return files
}

// toolgui/tgexec/web.go
func (e *WebExecutor) handleAssets(resp http.ResponseWriter, req *http.Request) {
	pageName := req.PathValue("name")
	body, isRootAssets := e.rootAssets[pageName]
	if !isRootAssets {
		resp.WriteHeader(http.StatusNotFound)
		return
	}

	resp.Write(body)
}

上一篇
Day15 Typescript + React
下一篇
Day17 Multipage
系列文
用 Golang 實作 streamlit 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言